﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SDL3;
using OpenTK.Graphics.OpenGL4;
using 飞机大战.shader;

namespace 飞机大战.scene
{
    internal partial class BackgroundDots : 飞机大战.core.IObject
    {

        private partial float[] SparsePointGenerator(int width, int height, double density)
        {
            this.totalPoints = (int)(width * height * density);
            float[] dots_ = new float[totalPoints * 2];
            // random.Next(2) - 1.0f
            for (int i = 0; i < totalPoints; i++)
            {
                dots_[i * 2] = (float)(random.NextDouble() * 2) - 1.0f;
                dots_[i * 2 + 1] = (float)(random.NextDouble() * 2) - 1.0f;
            }
            return dots_;
        }

        private partial void MoveSparsePoint(SDL.FPoint fPoint)
        {
            if (dots_ == null)
            {
                return;
            }
            for (int i = 0; i < this.totalPoints; i++)
            {
                dots_[i * 2] = (dots_[i * 2] + 3.0f + fPoint.X) % 2.0f - 1.0f;
                dots_[i * 2 + 1] = (dots_[i * 2 + 1] + 3.0f + fPoint.Y) % 2.0f - 1.0f;
            }
        }

        private unsafe partial void UpdatePointBuffer()
        {
            if (dots_ == null)
            {
                throw new InvalidOperationException("dots_ 数组未初始化。");
            }

            fixed (float* ptr = dots_)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferObject);
                GL.BufferData(BufferTarget.ArrayBuffer, dots_.Length * sizeof(float), (IntPtr)ptr, BufferUsageHint.DynamicDraw);
            }
        }

        public partial void Init()
        {
            GL.ClearColor(0.1f, 0.1f, 0.1f, 1.0f);
            dots_ = SparsePointGenerator(game.Width_, game.Height_, 0.001);
            shader_ = new DotShader.Shader();
            _vertexArrayObject = GL.GenVertexArray();
            _vertexBufferObject = GL.GenBuffer();

            GL.BindVertexArray(_vertexArrayObject);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferObject);

            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 2 * sizeof(float), 0);

            GL.EnableVertexAttribArray(0);

            UpdatePointBuffer();
        }

        public partial void Clean()
        {
            dots_ = null;
        }

        public partial void HandleEvents(SDL.Event event_)
        {

        }

        public partial void Render()
        {
            shader_.Use();
            // 2. 绑定顶点数组
            GL.BindVertexArray(_vertexArrayObject);
            UpdatePointBuffer();
            // 4. 实际绘制调用
            GL.DrawArrays(PrimitiveType.Points, 0, totalPoints);
        }

        public partial void Update(float dt)
        {
            MoveSparsePoint(new SDL.FPoint() { X = 0, Y = -0.0000000005f * dt});

            // SDL.Log($"{(0.00000005f * dt)}");
        }
    }
}
